﻿#pragma once
#include "DataFifo.h"

class jacx_fifo
{
public:
	jacx_fifo()
	{
		data_fifo.reset_size(1024);
	}
	~jacx_fifo() {}

	/**
	 * @brief 追加数据到末尾
	 * @param src_ 指针
	 * @param len_ 长度
	 * @return 实际添加的数据长度
	*/
	int push_back(const void* src_, size_t len_)
	{
		return data_fifo.push_back(src_, len_);
	}

	/**
	 * @brief 剩余可用空间
	 * @return 剩余空间长度，byte
	*/
	size_t remain_size()
	{
		return data_fifo.remain_size();
	}

	/**
	 * @brief 获取1个数据包
	 * @param dst_ 保存位置
	 * @param max_ 最大长度
	 * @return 实际获取到数据长度
	*/
	int get_pack(void* dst_, size_t max_)
	{
		assert(dst_);
		assert(max_);

		int drop = 0;
		while (data_fifo.size() >= 10)
		{
			if (data_fifo[0] != 0xb5 || data_fifo[1] != 0x62)
			{
				data_fifo.pop_front_count();
				++drop;
				continue;
			}
			if (drop)
				//log_sys->debug("radio msg dropd {} byte", drop);
			drop = 0;

			uint16_t pack_sz = data_fifo[7] + 8;

			if (data_fifo.size() < pack_sz + 2)
				return 0;

			uint8_t cka = 0, ckb = 0;
			for (int i = 2; i < pack_sz; ++i)
			{
				cka += data_fifo[i];
				ckb += cka;
			}
			if (cka == data_fifo[pack_sz] &&
				ckb == data_fifo[pack_sz + 1])
			{
				pack_sz = std::min((int)max_, pack_sz + 2);
				if (data_fifo.pop_front(dst_, pack_sz))
					return pack_sz;
			}
			else
			{
				data_fifo.pop_front();
				//log_sys->debug("radio sum check failed,id={} ,seq={}", data_fifo[4], data_fifo[5]);
			}
		}
		return 0;
	}

private:
	DataFifo<uint8_t> data_fifo;
	bool has_pack = false;


};